package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.constant.BspsAppParamConstant;
import cc.rengu.igas.bsps.common.dao.BspsMchntBaseInfoMapper;
import cc.rengu.igas.bsps.common.dao.impl.BspsMchntBaseInfoMapperImpl;
import cc.rengu.igas.bsps.common.entity.MchntBaseInfo;
import cc.rengu.igas.bsps.common.enums.BspsMchntTypeEnum;
import cc.rengu.igas.bsps.common.enums.MchntTypeEnum;
import cc.rengu.igas.bsps.common.enums.RespCodeEnum;
import cc.rengu.igas.bsps.core.service.base.ManageService;
import cc.rengu.igas.bsps.facade.request.GenerateDynamicQrCodeRequest;
import cc.rengu.igas.bsps.facade.response.GenerateDynamicQrCodeResponse;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.MchntOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.SysParamMapper;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MchntOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.SysParamMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.BizStatusEnum;
import cc.rengu.oltp.service.common.enums.OrderStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 赵奎伍
 * @Description 生成动态收款码
 * @date 2020/4/2
 */
public class GenerateDynamicQrCodeService extends ManageService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        GenerateDynamicQrCodeRequest generateDynamicQrCodeRequest = new GenerateDynamicQrCodeRequest();
        ConvertUtil.convertOutput(generateDynamicQrCodeRequest);
        return generateDynamicQrCodeRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        GenerateDynamicQrCodeRequest requestParams = (GenerateDynamicQrCodeRequest) request;
        GenerateDynamicQrCodeResponse responseParams = new GenerateDynamicQrCodeResponse();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        String orderAmt = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.ORDER_AMT);
        /* 参数合法性检查 */
        rglog.info("动态码参数必填性校验");
        if (StringUtil.isEmptyOrNull(requestParams.getUserId()) || StringUtil.isEmptyOrNull(requestParams.getMchntNo())) {
            rglog.error("接口上传参数不合法,userId:<{}>,mchntNo:<{}>,orderExpiryTime:<{}>", requestParams.getUserId(), requestParams.getMchntNo(), requestParams.getOrderExpiryTime());
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }

        if (StringUtil.isEmptyOrNull(requestParams.getTransAmt())) {
            requestParams.setTransAmt(orderAmt);
        }
        String instId = requestParams.getHeader().getInstId();
        String txnNum = requestParams.getHeader().getTxnNum();
        SysParamMapper sysParamMapper = new SysParamMapperImpl();
        //开通云闪付
        /*判断条件修改：从系统参数表获取标志字段*/
        SysParam qrCodeTypeVal, dynamicQrCodeTypeVal;
        qrCodeTypeVal = sysParamMapper.selectSysParamByPrimaryKey(instId, ShareParamConstant.MCHNT_SERVICE, "qrCodeType");
        dynamicQrCodeTypeVal = sysParamMapper.selectSysParamByPrimaryKey(instId, ShareParamConstant.MCHNT_SERVICE, "dynamicQrCodeType");
        StringBuilder qrCode = new StringBuilder();
        if (null != qrCodeTypeVal &&
                null != dynamicQrCodeTypeVal &&
                !StringUtil.isEmptyOrNull(qrCodeTypeVal.getParamValue()) &&
                !StringUtil.isEmptyOrNull(dynamicQrCodeTypeVal.getParamValue()) &&
                "Y".equals(qrCodeTypeVal.getParamStatus()) &&
                "Y".equals(dynamicQrCodeTypeVal.getParamStatus()) &&
                "CUPS".equals(qrCodeTypeVal.getParamValue()) &&
                "CUPS".equals(dynamicQrCodeTypeVal.getParamValue())) {
            //获取银联二维码的生成机构号
            rglog.info("===开通云闪付，银标码");
            String encry = encryptData(instId, sysSeqNum);
            SysParam unionPayCode = sysParamMapper.selectSysParamByPrimaryKey(instId, BspsAppParamConstant.MCHNT_PARAM_TYPE, BspsAppParamConstant.MCHNT_QRCODE_DOMAIN_NAMEB);
            if (null == unionPayCode) {
                rglog.error("批量申请收款聚合码服务处理失败！机构二维码类型为银联二维码，获取法人行在银联的机构号失败！instId:{}", instId);
                throw new BizException(RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespCode(), RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespDesc());
            }
            qrCode.append(unionPayCode.getParamValue()).append("/inf=D").append(encry);
        } else {
            rglog.info("==未开通云闪付，本行码");
            qrCode.append(machtGetQrUrl(instId));
        }
        rglog.info("创建用户订单");
        UserOrderInfo userOrderInfo = new UserOrderInfo();
        userOrderInfo.setInstId(instId);
        userOrderInfo.setTxnDate(DateUtil.getCurrentDate());
        userOrderInfo.setTxnTime(DateUtil.getCurrentTime());
        userOrderInfo.setTxnNum(txnNum);
        userOrderInfo.setBizType(requestParams.getHeader().getBizType());
        userOrderInfo.setMchntOrderId(requestParams.getHeader().getTraceNo());//商户订单号 必输 系统流水号
        userOrderInfo.setSysSeqNum(sysSeqNum);//系统流水号 必输
        userOrderInfo.setOrderCreateTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));// 订单创建时间 必输
        userOrderInfo.setOrderExpiryTime(requestParams.getOrderExpiryTime());//订单有效期 必输 当前时间
        userOrderInfo.setOrderStatus(OrderStatusEnum.INIT.getStatus());//订单状态 必输
        userOrderInfo.setBizStatus(BizStatusEnum.INIT.getStatus());
        userOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        userOrderInfo.setOrderDesc(requestParams.getOrderDesc());
        String mchntType = xmlTreeUtil.getXmlTreeStringValue("mchntType");
        //平台商户/集团商户/代理商商户号
        if (BspsMchntTypeEnum.AGENT_MCHNT.getMchntType().equals(mchntType) || BspsMchntTypeEnum.PLAT_MCHNT.getMchntType().equals(mchntType) || BspsMchntTypeEnum.GROUP_MCHNT.getMchntType().equals(mchntType)) {
            userOrderInfo.setGroupMchntNo(requestParams.getMchntNo());
        }
        /* 用户订单号赋值 */
        OrderService orderService = new OrderServiceImpl();
        userOrderInfo.setUserOrderId(orderService.generateUserOrderId());
        userOrderInfo.setOrderUrl(qrCode.toString());
        userOrderInfo.setMsgSrcId("OPMS");
        userOrderInfo.setTransChannelId("OPMS");
        userOrderInfo.setOrderCcy("156");
        Map<String, String> orderExtraInfo = new HashMap<>();
        orderExtraInfo.put("qrCodeType", "1");
        userOrderInfo.setOrderExtraInfo(JSON.toJSONString(orderExtraInfo));


        /*设置订单有效时间根据上送的有效时间，以分钟计算，如果上送按上送计算，如果未上送默认一分钟*/
        /*默认3分钟时间*/
        long futuretimes = System.currentTimeMillis() + 3 * 60 * 1000;
        String epiryTime = DateUtil.getDateByTimeStamp(futuretimes, "yyyyMMddHHmmss");
        String transAmt;
        userOrderInfo.setOrderExpiryTime(epiryTime);
        if (StringUtil.isEmptyOrNull(requestParams.getTransAmt())) {
            /* 订单未上送金额，有用户输入金额*/
            transAmt = "0.00";
            userOrderInfo.setOrderAmt("");
            userOrderInfo.setNeedPayAmt("");
        } else {
            transAmt = requestParams.getTransAmt();
            /**交易金额数据*/
            transAmt = AmountUtil.checkAmt(transAmt, 2, false);
            userOrderInfo.setOrderAmt(transAmt);
            userOrderInfo.setNeedPayAmt(transAmt);
            userOrderInfo.setRealPayAmt(transAmt);
        }

        //查询商户
        BspsMchntBaseInfoMapper mchntBaseInfoMapper = new BspsMchntBaseInfoMapperImpl();
        MchntBaseInfo mchntBaseInfo = mchntBaseInfoMapper.selectBspsMchntBaseInfoByPrimaryKey(instId, requestParams.getMchntNo());
        /* 开启数据库事务 */
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.OLTP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.OLTP_POOL_NAME);
        }
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();
        int iReturnCode;

        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        iReturnCode = userOrderInfoMapper.insertUserOrderInfo(userOrderInfo);
        if (0 != iReturnCode) {
            dbsUtil.dbsEndTransaction(false);
            rglog.error("登记用户信息表失败,iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespCode(), RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespDesc());
        }
        /*生成商户订单*/
        MchntOrderInfo mchntOrderInfo = new MchntOrderInfo();
        BeanUtil.beanCopy(userOrderInfo, mchntOrderInfo);
        mchntOrderInfo.setBizProdCode(txnInfo.getSrcTxnAuthCfg().getBizProdCode());
        mchntOrderInfo.setMchntNo(requestParams.getMchntNo());
        mchntOrderInfo.setOrderAmt(transAmt);
        mchntOrderInfo.setIndustryType(mchntBaseInfo.getIndustryType());
        mchntOrderInfo.setMchntName(mchntBaseInfo.getMchntName());
        mchntOrderInfo.setAcqInstCode(mchntBaseInfo.getSignInstId());
        mchntOrderInfo.setRealSettleFlag("N");
        mchntOrderInfo.setTransStatus("0");
        mchntOrderInfo.setOrderCcy("156");
        mchntOrderInfo.setUserId(requestParams.getUserId());
        mchntOrderInfo.setRealSettleAmt(transAmt);
        if (MchntTypeEnum.CHAIN_MCHNT_STORE.getMchntType().equals(mchntBaseInfo.getMchntType())) {
            mchntOrderInfo.setChainMchntNo(mchntBaseInfo.getChainMchntNo());
        }
        MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
        iReturnCode = mchntOrderInfoMapper.insertMchntOrderInfo(mchntOrderInfo);
        if (0 != iReturnCode) {
            dbsUtil.dbsEndTransaction(false);
            rglog.error("登记用户信息表失败,iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespCode(), RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespDesc());
        }
        dbsUtil.dbsEndTransaction(true);
        /* 组装应答报文 */
        BizResponse<GenerateDynamicQrCodeResponse> bizResponse = new BizResponse<>();
        responseParams.setMchntOrderId(userOrderInfo.getUserOrderId());
        responseParams.setOrderAmt(userOrderInfo.getOrderAmt());
        responseParams.setOrderExpiryTime(userOrderInfo.getOrderExpiryTime());
        responseParams.setOrderUrl(userOrderInfo.getOrderUrl());
        responseParams.setSysSeqNum(userOrderInfo.getSysSeqNum());
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(responseParams);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        GenerateDynamicQrCodeResponse generateDynamicQrCodeResponse = (GenerateDynamicQrCodeResponse) bizResponse.getResult();
        ConvertUtil.convertInput(generateDynamicQrCodeResponse);
    }

    /**
     * 加密数据
     *
     * @param instId  机构号
     * @param traceNo 待加密字符串
     * @return 加密后结果
     */
    private String encryptData(String instId, String traceNo) throws Exception {
        // 8位序号
        if (StringUtil.isEmptyOrNull(traceNo)) {
            rglog.error("申请收款聚合码服务处理失败! instId:{}", instId);
            throw new BizException(RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespCode(), RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespDesc());
        }

        return traceNo;
    }

    /**
     * 多个商户订单生成二维码URL
     * 银行域名+D+ 系统流水号
     *
     * @param instId 机构号
     * @return 二维码URL
     */
    private String machtGetQrUrl(String instId) throws Exception {
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParamInfo = sysParamService.getSysParamInfo(instId, BspsAppParamConstant.MCHNT_PARAM_TYPE, BspsAppParamConstant.INST_DOMAIN_NAME);
        if (null == sysParamInfo) {
            rglog.info("法人行域名未配置，instId:<{}>", instId);
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        //调用加密机平台进行 国密算法加密
        return sysParamInfo.getParamValue().concat("inf=D").concat(encryptData(instId, sysSeqNum));

    }

}
